package edu.hz.service.impl;

import edu.hz.dao.ClazzMapper;
import edu.hz.dao.GradeMapper;
import edu.hz.dao.UserDonationMapper;
import edu.hz.dao.UserMapper;
import edu.hz.enums.Gender;
import edu.hz.enums.UserTitle;
import edu.hz.model.dto.UserContributeDto;
import edu.hz.model.dto.UserInfoDto;
import edu.hz.model.dto.UserLoginDto;
import edu.hz.model.dto.UserRegisterDto;
import edu.hz.model.entity.UserDonationEntity;
import edu.hz.model.entity.UserEntity;
import edu.hz.service.UserService;
import edu.hz.util.PasswordUtil;
import edu.hz.util.web.ApiResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
public class UserServiceImpl implements UserService {

    @Resource
    UserMapper userMapper;

    @Resource
    GradeMapper gradeMapper;

    @Resource
    ClazzMapper clazzMapper;

    @Value("${login.maxAttempts}")
    private int maxLoginAttempts;

    @Resource
    private UserDonationMapper userDonationMapper;

    @Override
    public List<UserInfoDto> allUsers() {
        List<UserEntity> userEntities = userMapper.getAllUsers();
        List<UserInfoDto> userInfos = new ArrayList<>();
        userEntities.forEach(u -> {
            UserInfoDto uf = new UserInfoDto();
            uf.setId(u.getId());
            uf.setUsername(u.getUsername());
            uf.setTitle(u.getTitle());
            userInfos.add(uf);
        });
        return userInfos;
    }

    @Override
    public ApiResponse<Void> addUser(UserRegisterDto userRegisterDto) {
        // 判断用户名是否重复
        if (isUsernameExists(userRegisterDto.getUsername())) {
            return ApiResponse.error("用户名已存在");
        }
        // 判断两次密码输入是否一致
        if (!userRegisterDto.getPassword().equals(userRegisterDto.getPasswordConfirm())) {
            return ApiResponse.error("两次输入的密码不一致");
        }
        // 判断年级是否存在（假设有个方法来判断）
        if (!isGradeExists(userRegisterDto.getGradeId())) {
            return ApiResponse.error("年级不存在");
        }
        // 判断班级是否存在（假设有个方法来判断）
        if (!isClazzExists(userRegisterDto.getClazzId())) {
            return ApiResponse.error("班级不存在");
        }
        // 判断性别是否正确
        if (userRegisterDto.getGender() < 0 || userRegisterDto.getGender() > 2) {
            return ApiResponse.error("性别不正确");
        }
        // 创建用户实体
        UserEntity user = new UserEntity();
        user.setUsername(userRegisterDto.getUsername());
        user.setStudentId(userRegisterDto.getSchoolId());
        user.setRealname(userRegisterDto.getRealname());
        user.setGender(Gender.fromValue(userRegisterDto.getGender()).getValue());
        user.setGradeId(userRegisterDto.getGradeId());
        user.setClazzId(userRegisterDto.getClazzId());

        // 生成密码盐值并加密密码
        String salt = PasswordUtil.generateSalt();
        String hashedPassword = PasswordUtil.hashPassword(userRegisterDto.getPassword(), salt);
        user.setPwd(hashedPassword);
        user.setPwdSalt(salt);

        // 设置初始称号
        user.setTitle(UserTitle.HEARTHED_PERSON.getTitle());

        // 插入用户到数据库
        userMapper.insertUser(user);

        return ApiResponse.success(null);
    }

    @Override
    public ApiResponse<String> login(UserLoginDto userLoginDto) {
        String username = userLoginDto.getUsername();
        String password = userLoginDto.getPassword();

        // 检查用户是否存在
        UserEntity user = userMapper.getUserByUsername(username);
        if (user == null) {
            return ApiResponse.error("用户不存在");
        }

        // 检查是否超过最大错误登录次数
        int attempts = user.getErrLoginCount();
        if (attempts >= maxLoginAttempts) {
            return ApiResponse.error("登录错误次数过多，已限制登录");
        }

        // 验证密码
        String hashedPassword = PasswordUtil.hashPassword(password, user.getPwdSalt());
        if (!hashedPassword.equals(user.getPwd())) {
            userMapper.updateErrLoginCount(user.getId(), attempts + 1);
            return ApiResponse.error("密码错误");
        }

        // 登录成功，重置错误次数
        userMapper.updateErrLoginCount(user.getId(), 0);
        return ApiResponse.success("登录成功");
    }

    @Override
    public ApiResponse<Void> userContribute(UserContributeDto userContributeDto) {
        UserDonationEntity userDonation = new UserDonationEntity();
        userDonation.setUserId(userContributeDto.getUserId());
        userDonation.setDonationId(userContributeDto.getDonationId());
        userDonation.setDonationType(userContributeDto.getDonationType().getValue());
        userDonation.setMoney(userContributeDto.getMoney());
        userDonation.setDonationTime(LocalDateTime.now());
        userDonation.setDetail(userContributeDto.getDetail());

        int result = userDonationMapper.insertUserDonation(userDonation);
        if (result > 0) {
            return ApiResponse.success(null);
        } else {
            return ApiResponse.error("捐赠失败，重试");
        }
    }

    private boolean isUsernameExists(String username) {
        return userMapper.getUserByUsername(username) != null;
    }


    private boolean isGradeExists(int gradeId) {
        return gradeMapper.countGradeById(gradeId) > 0;
    }

    private boolean isClazzExists(int clazzId) {
        return clazzMapper.countClazzById(clazzId) > 0;
    }

}
